﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;
using SoftwareConsulting.BI11.Controls.Properties;
using System.Drawing;

namespace SoftwareConsulting.BI11.Controls
{
    /// <summary>
    /// Класс настраиваемого датагрида
    /// </summary>
    public class CustomizedDataGrid: DataGridView
    {
        private ContextMenuStrip _contextMenu; //контекстное меню
        private ToolStripItem _chooseColumnsItem; //элемент для выбора столбцов
        private ToolStripSeparator _separator; //элемент-разделитель
        private ToolStripItem _deleteSelectedRowsItem; //элемент для удаления выделенных строк
        private Point _lastMouseDownPoint; //точка последнего нажатия клавиши мышкой
        private int _originalContextMenuItemsCount;//количество оригинальных пунктов контекстного меню

        /// <summary>
        /// Обрабатывает выбор пункта контекстного меню "Выбрать столбцы..."
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void chooseColumns_Click(object sender, EventArgs args)
        {
            CustomizedDataGridChooseColumnsDialog dialog = new CustomizedDataGridChooseColumnsDialog(this);
            dialog.ShowDialog(this);
        }

        /// <summary>
        /// Обрабатывает выбор пункта контекстного меню "Удалить выделенные строки"
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void deleteSelectedRows_Click(object sender, EventArgs args)
        {
            int c = SelectedRows.Count;
            for (int i = c - 1; i >= 0; i--)
            {
                var row = SelectedRows[i];
                if (row.Index == NewRowIndex)
                    continue;
                Rows.Remove(row);
            }
        }

        /// <summary>
        /// Обрабатывает появление контекстного меню
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void _contextMenu_Opening(object sender, CancelEventArgs args)
        {
            bool isHeader = _lastMouseDownPoint.Y <= this.ColumnHeadersHeight;
            bool isAllowedToDeleteRows = AllowUserToDeleteRows;
            bool haveAnyAdditionalItems = _contextMenu.Items.Count != _originalContextMenuItemsCount;
            _chooseColumnsItem.Visible = isHeader;
            _separator.Visible = isHeader && isAllowedToDeleteRows;
            _deleteSelectedRowsItem.Visible = isAllowedToDeleteRows;
            _deleteSelectedRowsItem.Enabled = isAllowedToDeleteRows && (SelectedRows.Count > 0);
            args.Cancel = !isHeader && !isAllowedToDeleteRows && !haveAnyAdditionalItems;
        }

        /// <summary>
        /// Обрабатывает нажатие кнопки мыши над датагридом
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void CustomizedDataGrid_MouseDown(object sender, MouseEventArgs args)
        {
            _lastMouseDownPoint = args.Location;
            if (args.Button != MouseButtons.Right)
                return;
            if (SelectionMode != DataGridViewSelectionMode.FullRowSelect)
                return; //не смог заставить корректно программно менять выделение с другими типами выделения
            int selectedRowIndex = Rows.GetFirstRow(DataGridViewElementStates.Displayed);
            if (selectedRowIndex == -1)
                return;
            while (!GetRowDisplayRectangle(selectedRowIndex, true).Contains(_lastMouseDownPoint))
            {
                selectedRowIndex = Rows.GetNextRow(selectedRowIndex, DataGridViewElementStates.Displayed);
                if (selectedRowIndex == -1)
                    return;//не нашли строку
            }
            //нашли строку, выделим ее
            for (int i = 0; i < Rows.Count; i++)
            {
                Rows[i].Selected = i == selectedRowIndex;
                if (SelectionMode != DataGridViewSelectionMode.FullRowSelect)
                {
                    for (int j = 0; j < Columns.Count; j++)
                    {
                        Rows[i].Cells[j].Selected = i == selectedRowIndex;
                    }
                }
            }
            //почему-то через цикл недостаточно, поэтому далее обход
            this.SetSelectedRowCore(selectedRowIndex, true);
            if (SelectionMode != DataGridViewSelectionMode.FullRowSelect)
            {
                for (int j = 0; j < Columns.Count; j++)
                {                    
                    this.SetSelectedCellCore(j, selectedRowIndex, true);                    
                }
            }
        }

        /// <summary>
        /// Конструктор класса
        /// </summary>
        public CustomizedDataGrid()
            : base()
        {            
            _contextMenu = new ContextMenuStrip();            
            _chooseColumnsItem = _contextMenu.Items.Add(Resources.BI_CUSTOMIZEDDATAGRID_CHOOSECOLUMNS);            
            _chooseColumnsItem.Click += new EventHandler(chooseColumns_Click);
            _separator = new ToolStripSeparator();
            _contextMenu.Items.Add(_separator);            
            _deleteSelectedRowsItem = _contextMenu.Items.Add(Resources.BI_CUSTOMIZEDDATAGRID_DELETESELECTEDROWS);                        
            _deleteSelectedRowsItem.Click += new EventHandler(deleteSelectedRows_Click);            
            _contextMenu.Opening += new System.ComponentModel.CancelEventHandler(_contextMenu_Opening);
            MouseDown += new MouseEventHandler(CustomizedDataGrid_MouseDown);
            this.ContextMenuStrip = _contextMenu;
            _originalContextMenuItemsCount = _contextMenu.Items.Count;
        }
    }
}
